package br.com.foxinline.servico;

import br.com.foxinline.generico.ServicoGenerico;
import br.com.foxinline.modelo.Aforamento;
import br.com.foxinline.modelo.Anexo;
import br.com.foxinline.modelo.Usuario;
import br.com.foxinline.util.Caracter;
import java.beans.Transient;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.Query;

/**
 *
 * @author laverson
 */
@Stateless
public class AforamentoServico extends ServicoGenerico<Aforamento> {

    @EJB
    UsuarioServico usuarioServico;
    private Long quantidadeRegistrosResults;
    private static String nomeEntidade = Aforamento.class.getSimpleName();

    public AforamentoServico() {
        super(Aforamento.class);
    }

    @Override
    public void save(Aforamento entity) {

        if (entity.getLivro() != null && entity.getLivro().isEmpty()) {
            entity.setLivro(null);
        }

        if (entity.getFolha() != null && entity.getFolha().isEmpty()) {
            entity.setFolha(null);
        }

        entity.setDataCriacao(new Date());
        entity.setCriadoPor(usuarioServico.getCurrentUser());
        entity.setAtivo(Boolean.TRUE);

        super.save(entity);
    }

    @Override
    public void update(Aforamento entity) {
        entity.setDataEdicao(new Date());
        entity.setEditadoPor(usuarioServico.getCurrentUser());

        super.update(entity);
        updateAnexos(entity);
    }

    @Override
    public void updateAnexos(Aforamento a) {

        a.setAnexos(getAnexos(a));
        super.updateAnexos(a);
    }

    public List<Anexo> getAnexos(Aforamento p) {
        String sql = "select a from " + p.getClass().getSimpleName() + " p join p.anexos a where p.id = " + p.getId();
        return getEntityManager().createQuery(sql).getResultList();
    }

    public List<String> numeroLivros(Usuario usuario) {

        String sql = "SELECT distinct a.livro FROM " + nomeEntidade + " a "
                + "JOIN a.criadoPor u ";

        if (usuario != null && usuario.getId() != null) {
            sql += "WHERE u.id = :usuarioId ";
        }

        sql += "ORDER BY a.livro asc";

        Query query = getEntityManager().createQuery(sql);

        if (usuario != null && usuario.getId() != null) {
            query.setParameter("usuarioId", usuario.getId());
        }

        return query.getResultList();
    }

    public Long quantidadeFolhaLivro(String numeroLivro, Usuario usuario) {

        String sql = "SELECT count(a) FROM " + nomeEntidade + " a JOIN a.criadoPor u WHERE ";

        if (numeroLivro == null) {
            sql += "a.livro is null AND ";
        } else {
            sql += "a.livro = :numeroLivro AND ";
        }

        if (usuario != null && usuario.getId() != null) {
            sql += "u.id = :usuarioId AND ";
        }

        sql += "1=1";

        Query query = getEntityManager().createQuery(sql);

        if (numeroLivro != null) {
            query.setParameter("numeroLivro", numeroLivro);
        }

        if (usuario != null && usuario.getId() != null) {
            query.setParameter("usuarioId", usuario.getId());
        }

        return (Long) query.getSingleResult();
    }

    public List<Aforamento> porLivroUsuario(String numeroLivro, Usuario usuario) {

        String sql = "SELECT a FROM " + nomeEntidade + " a JOIN a.criadoPor u WHERE ";

        if (numeroLivro == null || numeroLivro.isEmpty()) {
            sql += "a.livro is null AND ";
        } else {
            sql += "a.livro = :numeroLivro AND ";
        }

        if (usuario != null && usuario.getId() != null) {
            sql += "u.id = :usuarioId AND ";
        }

        sql += "1=1";

        Query query = getEntityManager().createQuery(sql);

        if (numeroLivro != null && !numeroLivro.isEmpty()) {
            query.setParameter("numeroLivro", numeroLivro);
        }

        if (usuario != null && usuario.getId() != null) {
            query.setParameter("usuarioId", usuario.getId());
        }

        return query.getResultList();
    }

    public List<Usuario> usuarios(Aforamento aforamento) {

        String sql = "SELECT distinct a.criadoPor FROM " + nomeEntidade + " a WHERE ";

        if (aforamento.getLivro() != null) {
            sql += "a.livro like :livro AND ";
        }
        if (aforamento.getCriadoPor() != null && aforamento.getCriadoPor().getId() != null) {
            sql += "a.criadoPor.id = :usuarioId AND ";
        }

        sql += "1=1 ORDER BY a.criadoPor.id";

        Query query = getEntityManager().createQuery(sql);

        if (aforamento.getLivro() != null) {
            query.setParameter("livro", aforamento.getLivro());
        }
        if (aforamento.getCriadoPor() != null && aforamento.getCriadoPor().getId() != null) {
            query.setParameter("usuarioId", aforamento.getCriadoPor().getId());
        }

        return query.getResultList();
    }

    public Long quantidadePorUsuarioEDia(Usuario usuario, Date dataInicial) {

        String sql = "SELECT count(a) FROM " + nomeEntidade + " a WHERE ";

        if (usuario != null && usuario.getId() != null) {
            sql += "a.criadoPor.id = :usuarioId AND ";
        }

        if (dataInicial != null) {
            sql += "a.dataCriacao =  :dataInicial ";
        }

        Query query = getEntityManager().createQuery(sql);

        if (usuario != null && usuario.getId() != null) {
            query.setParameter("usuarioId", usuario.getId());
        }
        if (dataInicial != null) {
            query.setParameter("dataInicial", dataInicial);
        }

        return (Long) query.getSingleResult();
    }

    @Override
    public List<Aforamento> find(Aforamento aforamento, Integer first, Integer pageSize) {
        String select = "SELECT aforamento ";
        String sql = "FROM " + nomeEntidade + " aforamento ";
        String orderBy = " order by aforamento.id asc";

        if ((aforamento.getForeiroCpf() != null && !aforamento.getForeiroCpf().isEmpty())
                || (aforamento.getForeiro() != null && !aforamento.getForeiro().isEmpty())) {

            sql += " JOIN aforamento.foreiros foreiro ";
        }

        sql += " where ";

        if (aforamento.getCartaNumero() != null && !aforamento.getCartaNumero().isEmpty()) {
            sql += " lower(aforamento.cartaNumero) like lower(:cartaNumero) and ";
        }

        if (aforamento.getCartaData() != null) {
            sql += " aforamento.cartaData = :cartaData and ";
        }

        if (aforamento.getContratoReferencia() != null && !aforamento.getContratoReferencia().isEmpty()) {
            sql += " lower(aforamento.contratoReferencia) like lower(:contratoReferencia) and ";
        }

        if (aforamento.getLivro() != null && !aforamento.getLivro().isEmpty()) {
            sql += " lower(aforamento.livro) like lower(:livro) and ";
        }

        if (aforamento.getFolha() != null && !aforamento.getFolha().isEmpty()) {
            sql += " lower(aforamento.folha) like lower(:folha) and ";
        }

        if (aforamento.getPrefeito() != null && !aforamento.getPrefeito().isEmpty()) {
            sql += " lower(aforamento.prefeito) like lower(:prefeito) and ";
        }

        if (aforamento.getSecretario() != null && !aforamento.getSecretario().isEmpty()) {
            sql += " lower(aforamento.secretario) like lower(:secretario) and ";
        }

        if (aforamento.getDespachoNumero() != null && !aforamento.getDespachoNumero().isEmpty()) {
            sql += " lower(aforamento.despachoNumero) like lower(:despachoNumero) and ";
        }

        if (aforamento.getDespachoData() != null) {
            sql += " aforamento.despachoData = :despachoData and ";
        }

        if (aforamento.getPeticaoRequerimentoNumero() != null && !aforamento.getPeticaoRequerimentoNumero().isEmpty()) {
            sql += " lower(aforamento.peticaoRequerimentoNumero) like lower(:peticaoRequerimentoNumero) and ";
        }

        if (aforamento.getPeticaoRequerimentoData() != null) {
            sql += " aforamento.peticaoRequerimentoData = :peticaoRequerimentoData and ";
        }

        if (aforamento.getForeiroCpf() != null && !aforamento.getForeiroCpf().isEmpty()) {
            sql += " lower(foreiro.cpf) like lower(:foreiroCpf) and ";
        }

        if (aforamento.getForeiro() != null && !aforamento.getForeiro().isEmpty()) {
            sql += " lower(foreiro.nome) like lower(:foreiro) and ";
        }

        if (aforamento.getZona() != null) {
            sql += " lower(aforamento.zona) like lower(:zona) and ";
        }

        if (aforamento.getEndereco() != null && !aforamento.getEndereco().isEmpty()) {
            sql += " lower(aforamento.endereco) like lower(:endereco) and ";
        }

        if (aforamento.getAutoMedicaoDemarcacao() != null && !aforamento.getAutoMedicaoDemarcacao().isEmpty()) {
            sql += " lower(aforamento.autoMedicaoDemarcacao) like lower(:autoMedicaoDemarcacao) and ";
        }

        if (aforamento.getAutoMedicaoDemarcacaoLivro() != null && !aforamento.getAutoMedicaoDemarcacaoLivro().isEmpty()) {
            sql += " lower(aforamento.autoMedicaoDemarcacaoLivro) like lower(:autoMedicaoDemarcacaoLivro) and ";
        }

        if (aforamento.getAutoMedicaoDemarcacaoFolha() != null && !aforamento.getAutoMedicaoDemarcacaoFolha().isEmpty()) {
            sql += " lower(aforamento.autoMedicaoDemarcacaoFolha) like lower(:autoMedicaoDemarcacaoFolha) and ";
        }

        sql += " aforamento.ativo = true ";

        Query query = getEntityManager().createQuery(select.concat(sql).concat(orderBy));

        setQuantidadeRegistros(sql, query, aforamento);

        setParameters(aforamento, query);

        if (first != null && pageSize != null) {
            query.setFirstResult(first).setMaxResults(pageSize);
        }

        return query.getResultList();
    }

    @Transient
    private void setParameters(Aforamento aforamento, Query query) {

        if (aforamento.getCartaNumero() != null && !aforamento.getCartaNumero().isEmpty()) {
            query.setParameter("cartaNumero", "%" + aforamento.getCartaNumero() + "%");
        }

        if (aforamento.getCartaData() != null) {
            query.setParameter("cartaData", aforamento.getCartaData());
        }

        if (aforamento.getContratoReferencia() != null && !aforamento.getContratoReferencia().isEmpty()) {
            query.setParameter("contratoReferencia", "%" + aforamento.getContratoReferencia() + "%");
        }

        if (aforamento.getLivro() != null && !aforamento.getLivro().isEmpty()) {
            query.setParameter("livro", "%" + aforamento.getLivro() + "%");
        }

        if (aforamento.getFolha() != null && !aforamento.getFolha().isEmpty()) {
            query.setParameter("folha", "%" + aforamento.getFolha() + "%");
        }

        if (aforamento.getPrefeito() != null && !aforamento.getPrefeito().isEmpty()) {
            query.setParameter("prefeito", "%" + aforamento.getPrefeito() + "%");
        }

        if (aforamento.getSecretario() != null && !aforamento.getSecretario().isEmpty()) {
            query.setParameter("secretario", "%" + aforamento.getSecretario() + "%");
        }

        if (aforamento.getDespachoNumero() != null && !aforamento.getDespachoNumero().isEmpty()) {
            query.setParameter("despachoNumero", "%" + aforamento.getDespachoNumero() + "%");
        }

        if (aforamento.getDespachoData() != null) {
            query.setParameter("despachoData", aforamento.getDespachoData());
        }

        if (aforamento.getPeticaoRequerimentoNumero() != null && !aforamento.getPeticaoRequerimentoNumero().isEmpty()) {
            query.setParameter("peticaoRequerimentoNumero", "%" + aforamento.getPeticaoRequerimentoNumero() + "%");
        }

        if (aforamento.getPeticaoRequerimentoData() != null) {
            query.setParameter("peticaoRequerimentoData", aforamento.getPeticaoRequerimentoData());
        }

        if (aforamento.getForeiroCpf() != null && !aforamento.getForeiroCpf().isEmpty()) {
            query.setParameter("foreiroCpf", "%" + Caracter.removecaracter(aforamento.getForeiroCpf()) + "%");
        }

        if (aforamento.getForeiro() != null && !aforamento.getForeiro().isEmpty()) {
            query.setParameter("foreiro", "%" + aforamento.getForeiro() + "%");
        }

        if (aforamento.getZona() != null) {
            query.setParameter("zona", "%" + aforamento.getZona().getNome() + "%");
        }

        if (aforamento.getEndereco() != null && !aforamento.getEndereco().isEmpty()) {
            query.setParameter("endereco", "%" + aforamento.getEndereco() + "%");
        }

        if (aforamento.getAutoMedicaoDemarcacao() != null && !aforamento.getAutoMedicaoDemarcacao().isEmpty()) {
            query.setParameter("autoMedicaoDemarcacao", "%" + aforamento.getAutoMedicaoDemarcacao() + "%");
        }

        if (aforamento.getAutoMedicaoDemarcacaoLivro() != null && !aforamento.getAutoMedicaoDemarcacaoLivro().isEmpty()) {
            query.setParameter("autoMedicaoDemarcacaoLivro", "%" + aforamento.getAutoMedicaoDemarcacaoLivro() + "%");
        }

        if (aforamento.getAutoMedicaoDemarcacaoFolha() != null && !aforamento.getAutoMedicaoDemarcacaoFolha().isEmpty()) {
            query.setParameter("autoMedicaoDemarcacaoFolha", "%" + aforamento.getAutoMedicaoDemarcacaoFolha() + "%");
        }
    }

    private void setQuantidadeRegistros(String sql, Query query, Aforamento aforamento) {

        String select = "SELECT count(aforamento) ";

        query = getEntityManager().createQuery(select + sql);

        setParameters(aforamento, query);

        quantidadeRegistrosResults = (Long) query.getSingleResult();
    }

    @Override
    public Long quantidadeRegistros() {
        return quantidadeRegistrosResults;
    }
}
